#ifndef DOCUMENTS_H_
#define DOCUMENTS_H_

#include <iostream>
#include <fstream>
#include "SQLite3.hpp"
#include "utils.h"
#include "filter.h"
namespace sdms
{
using namespace utils;
using namespace sqlite;
using namespace std;
class Filter;
class attachment
{
public:
    attachment():id(0),is_modified(false) {}
    ~attachment() {}
    void open();
    void remove();
    //void update();
    void insert(unsigned int sid);
    unsigned int id;
    string uri;
    string thumb;
    string mime;
    //如果存在annotations/highlights，说明曾经编辑过
    //jump to zotero with zotero attachment url link.
    bool is_modified;
};
class note
{
public:
    note():id(0) {}
    ~note() {}
    void open();
    void remove();
    void update();
    void insert(unsigned int sid);
    unsigned int id;
    string title; //or use the note(html content)?
private:
    unsigned int sourceid;
};
class tag
{
public:
    tag():id(0) {}
    ~tag() {}
    void remove();
    void insert();
    unsigned int id;
    unsigned int type;//1 means the tag is added by zotero system, not human.
    unsigned int count;
    string name;

};
class reading
{
public:
    reading():id(0),plan(""),finish("") {}
    ~reading() {}
    unsigned int id; //itemID
    string plan;//计划在什么时间完成阅读
    string finish;
};

class readinglist
{
public:
    readinglist() {}
    ~readinglist() {}
    void insert(unsigned int itemid);
    void finish(unsigned int id);
    vector<reading> getreadings();
};
class writing
{
public:
    writing():id(0) {}
    ~writing() {}
    void insert();
    void open();
    void create();
    unsigned int id;
    string name;//title
    unsigned int count;
    vector<unsigned int> reference;
};
class writinglist
{
public:
    void open();
    void current(unsigned int id);//当前正在撰写的文章
};
class publisher
{
public:
    publisher():count(0) {}
    ~publisher() {}
    string name;
    unsigned int count;
};

class document
{
public:
    document():id(0),click(0) {}
    ~document() {}
    unsigned int id;
    unsigned int click;
    string uri;//主要附件
    string thumb;//第一位的缩略图或图标
    string mime;
    string name;
    bool has_anno;//or has highlight
    string type;
    string publisher;//presser or journal
    string date;//which date to be used? date in fields or clientsDateModified
private:
    string key; //used for local storage
};
class category //collections, or publisher
{
public:
    category():count(0) {}
    ~category() {}
    unsigned int count;
    string name;
};
class theme
{
public:
    theme():id(0),count(0) {}
    ~theme() {}
    unsigned int id;
    unsigned int count;
    string name;
    string comment;
};
class searchfolder
{
public:
    searchfolder():id(0) {}
    ~searchfolder() {}
    unsigned int id;
    string name;
    string content;
};
class documents
{
public:
    documents();
    documents(const string&);//目录必须存在，否则必须先创建
    virtual ~documents();
    documents(const documents& other);
    documents& operator=(const documents& other);
    string get_dbfile() const;
    void set_dbfile(const string&);
    bool data_export(const string&);
    bool data_import(const string&);
    bool add(document*);
    bool add(category*);
    bool add(writing*);
    bool add(tag*);
    bool add(reading*);
    bool add(searchfolder*);
    bool update(const tag*);
    bool update(const writing*);
    bool update(const category*);
    bool update(const document*);
    bool update(std::vector<std::string>&,const document*);//批量更新TAGS
    bool update(writing*,const document*);//更新writingItems表
    bool update(category*,const document*);
    bool update(tag*,const document*);
    bool update(const searchfolder*);
    bool del(const tag* t);
    bool del(const tag*,const document*);
    bool del(const writing*);
    bool del(const writing*,const document*);
    bool del(const reading&,const document&);
    bool del(const category*,bool recursive=false);
    bool del(const category*,const document*);
    bool del(const document*);
    bool rdel(const category* t);//递归删除方式
    bool del(const searchfolder*);
    vector<document> getbook(unsigned int=0);
    vector<document> getarticle(unsigned int=0);
    vector<document> getdocument(unsigned int=0);
    vector<document> getnopdfdocument();
    vector<document> getdocument(const Filter* f);
    vector<publisher> getpublisher(unsigned int=0);
    vector<publisher> bookpublisher(unsigned int=0);
    vector<publisher> articlepublisher(unsigned int=0);
    vector<publisher> nopdfpublisher(unsigned int=0);
    vector<writing> getwriting(unsigned int=0);
    vector<writing> getwriting(const vector<unsigned int>& docid);//取共同分类
    vector<reading> getreading(unsigned int=0);
    bool inreading(const vector<unsigned int>&);//get the intersect reading
    vector<reading> getmonthreading(unsigned int,unsigned int);
    vector<tag> gettag(unsigned int=0);
    vector<tag> gettag(const vector<unsigned int>& docid);
    vector<attachment> getattachment(const document&);

    vector<theme> gettheme(const document*);
    vector<category> getcategory(unsigned int=0);
    vector<category> getcategory(const vector<unsigned int>& docid);//取多个DOC的共同TAG
    vector<searchfolder> getsearchfolder(unsigned int=0);
    vector<unsigned int>getfilter(const string& sql);
private:
    void createdb();
    vector<publisher> _publisher(const string& sql);
    vector<document> _document(const string& sql);
    vector<tag> _tag(const string& sql);
    vector<writing> _writing(const string& sql);
    vector<reading> _reading(const string& sql);
    vector<attachment> _attachment(const string& sql);

    string dbfile;
    SQLite3 db;
};
}
#endif
